home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / xlib04.zip / XCBITMAP.ASM < prev    next >
Assembly Source File  |  1992-11-12  |  13KB  |  423 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XCBITMAP
  3. ; This module was written by Matthew MacKenzie
  4. ; matm@eng.umd.edu
  5. ;
  6. ; Compiled bitmap  functions all MODE X 256 Color resolutions
  7. ;
  8. ; Compile with Tasm.
  9. ; C callable.
  10. ;
  11. ; egg@dstos3.dsto.gov.au
  12. ; teg@bart.dsto.gov.au
  13. ;-----------------------------------------------------------------------
  14.  
  15. include xlib.inc
  16. include xcbitmap.inc
  17.  
  18. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  19. ; _x_compile_bitmap
  20. ;
  21. ; Compile a linear bitmap to generate machine code to plot it
  22. ; at any required screen coordinates FAST. Faster than blits
  23. ; using planar bitmaps as in module XPBIITMAP
  24. ;
  25. ; C near-callable as:
  26. ; int x_compile_bitmap  (WORD logical_screen_width,
  27. ;                        char far * bitmap, char far * output);
  28. ;
  29. ; The logical width is in bytes rather than pixels.
  30. ;
  31. ; All four main registers are totaled.
  32. ;
  33. ;  The source linear bitmaps have the following structure:
  34. ;
  35. ;  BYTE 0                 The bitmap width in pixels  range 1..255
  36. ;  BYTE 1                 The bitmap height in rows   range 1..255
  37. ;  BYTE 2..n              The width*height bytes of the bitmap in
  38. ;                         cloumn row order
  39. ;
  40. ; The returned value is the size of the compiled bitmap, in bytes.
  41.  
  42.  
  43. ; accessory macros to save typing (what else?)
  44. Emitb macro arg
  45.     mov byte ptr es:[di],&arg&
  46.     inc di
  47.     endm
  48.  
  49. Emitw macro arg
  50.     mov word ptr es:[di],&arg&
  51.     add di,2
  52.     endm
  53.  
  54. ; opcodes emitted by _x_compile_sprite
  55. ROL_AL          equ 0c0d0h              ; rol al
  56. SHORT_STORE_8   equ 044c6h              ; mov [si]+disp8,  imm8
  57. STORE_8         equ 084c6h              ; mov [si]+disp16, imm8
  58. SHORT_STORE_16  equ 044c7h              ; mov [si]+disp8,  imm16
  59. STORE_16        equ 084c7h              ; mov [si]+disp16, imm16
  60. ADC_SI_IMMED    equ 0d683h              ; adc si,imm8
  61. OUT_AL          equ 0eeh                ; out dx,al
  62. RETURN          equ 0cbh                ; ret
  63.  
  64.  
  65. .data
  66.  
  67. align 2
  68. ColumnMask      db      011h,022h,044h,088h
  69.  
  70.  
  71. .code
  72.  
  73.     align   2
  74. _x_compile_bitmap proc
  75. ARG   logical_width:word,bitmap:dword,output:dword
  76. LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk
  77.     push bp
  78.     mov  bp, sp                        ; caller's stack frame
  79.     sub  sp,LocalStk                   ; local space
  80.     push si
  81.     push di
  82.     push ds
  83.  
  84.     mov word ptr [scanx],0
  85.     mov word ptr [scany],0
  86.     mov word ptr [outputx],0
  87.     mov word ptr [outputy],0
  88.     mov word ptr [column],0
  89.     mov word ptr [set_column],0
  90.  
  91.     lds si,[bitmap]                   ; 32-bit pointer to source bitmap
  92.  
  93.     les di,[output]                   ; 32-bit pointer to destination stream
  94.  
  95.     lodsb                             ; load width byte
  96.     xor ah,ah                         ; convert to word
  97.     mov [bwidth],ax                   ; save for future reference
  98.     mov bl,al                         ; copy width byte to bl
  99.     lodsb                             ; load height byte. Is word since ah=0
  100.     mul bl                            ; mult height word by width byte
  101.     mov [input_size],ax               ;  giving pixel total and save
  102.  
  103. @@MainLoop:
  104.         mov bx,[scanx]                ; position in original bitmap
  105.         add bx,[scany]
  106.  
  107.     mov al,[si+bx]                ; get pixel
  108.     or  al,al                     ; skip empty pixels
  109.     jnz @@NoAdvance
  110.     jmp @@Advance
  111. @@NoAdvance:
  112.  
  113.             mov dx,[set_column]
  114.             cmp dx,[column]
  115.             je @@SameColumn
  116. @@ColumnLoop:
  117.                 Emitw ROL_AL          ; emit code to adjust sprite
  118.                 Emitw ADC_SI_IMMED
  119.                 Emitb 0
  120.  
  121.                 inc dx
  122.                 cmp dx,[column]
  123.                 jl @@ColumnLoop
  124.  
  125.                 Emitb OUT_AL          ; emit code to set VGA mask for new column
  126.                 mov [set_column],dx
  127. @@SameColumn:
  128.             mov dx,[outputy]          ; calculate output position
  129.             add dx,[outputx]
  130.             sub dx,128
  131.  
  132.             add word ptr [scanx],4
  133.             mov cx,[scanx]            ; within four pixels of right edge?
  134.             cmp cx,[bwidth]
  135.             jge @@OnePixel
  136.  
  137.             inc word ptr [outputx]
  138.             mov ah,[si+bx+4]           ; get second pixel
  139.             or   ah,ah
  140.             jnz  @@TwoPixels
  141. @@OnePixel:
  142.                     cmp dx,127                ; can we use shorter form?
  143.                     jg @@OnePixLarge
  144.                     cmp dx,-128
  145.                     jl @@OnePixLarge
  146.                         Emitw SHORT_STORE_8
  147.                         Emitb dl              ; 8-bit position in output
  148.                         jmp @@EmitOnePixel
  149. @@OnePixLarge:
  150.                         Emitw STORE_8
  151.                         Emitw dx              ; position in output
  152. @@EmitOnePixel:
  153.                     Emitb al
  154.             jmp short @@Advance
  155. @@TwoPixels:
  156.                     cmp dx,127
  157.                     jg @@TwoPixLarge
  158.                     cmp dx,-128
  159.                     jl @@TwoPixLarge
  160.                         Emitw SHORT_STORE_16
  161.                         Emitb dl              ; 8-bit position in output
  162.                         jmp @@EmitTwoPixels
  163. @@TwoPixLarge:
  164.                         Emitw STORE_16
  165.                         Emitw dx              ; position in output
  166. @@EmitTwoPixels:
  167.                     Emitw ax
  168.  
  169. @@Advance:
  170.         inc word ptr [outputx]
  171.         mov ax,[scanx]
  172.         add ax,4
  173.         cmp ax,[bwidth]
  174.         jl @@AdvanceDone
  175.             mov dx,[outputy]
  176.             add dx,[logical_width]
  177.             mov cx,[scany]
  178.             add cx,[bwidth]
  179.             cmp cx,[input_size]
  180.             jl @@NoNewColumn
  181.                 inc word ptr [column]
  182.                 mov cx,[column]
  183.                 cmp cx,4
  184.                 je @@Exit               ; Column 4: there is no column 4.
  185.                 xor cx,cx             ; scany and outputy are 0 again for
  186.                 mov dx,cx             ; the new column
  187. @@NoNewColumn:
  188.             mov [outputy],dx
  189.             mov [scany],cx
  190.             mov word ptr [outputx],0
  191.             mov ax,[column]
  192. @@AdvanceDone:
  193.             mov [scanx],ax
  194.     jmp @@MainLoop
  195.  
  196. @@Exit:
  197.     Emitb RETURN
  198.     mov ax,di
  199.     sub ax,word ptr [output]          ; size of generated code
  200.  
  201.     pop ds
  202.     pop di
  203.     pop si
  204.     mov sp,bp
  205.     pop bp
  206.  
  207.     ret
  208. _x_compile_bitmap endp
  209.  
  210.  
  211. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  212. ; _x_sizeof_compiled_bitmap
  213. ;
  214. ; This function follows the same algorithm as the one above,
  215. ; but does not generate a new object.  Its sole purpose is to
  216. ; determine how much space the compiled bitmap will require.
  217. ;
  218. ; C near-callable as:
  219. ; int x_sizeof_compiled_bitmap  (WORD logical_screen_width,
  220. ;                                char far * bitmap);
  221. ;
  222. ; The logical width is in bytes rather than pixels.
  223. ;
  224. ; All four main registers are totaled.
  225. ;
  226. ;  The source linear bitmaps have the following structure:
  227. ;
  228. ;  BYTE 0                 The bitmap width in pixels  range 1..255
  229. ;  BYTE 1                 The bitmap height in rows   range 1..255
  230. ;  BYTE 2..n              The width*height bytes of the bitmap in
  231. ;                         cloumn row order
  232. ;
  233. ; The returned value is the size of the compiled bitmap, in bytes.
  234.  
  235.  
  236.     align   2
  237. _x_sizeof_compiled_bitmap proc
  238. ARG   logical_width:word,bitmap:dword
  239. LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk
  240.     push bp
  241.     mov  bp, sp                        ; caller's stack frame
  242.     sub  sp,LocalStk                   ; local space
  243.     push si
  244.     push di
  245.     push ds
  246.  
  247.     mov word ptr [scanx],0
  248.     mov word ptr [scany],0
  249.     mov word ptr [outputx],0
  250.     mov word ptr [outputy],0
  251.     mov word ptr [column],0
  252.     mov word ptr [set_column],0
  253.  
  254.     lds si,[bitmap]                   ; 32-bit pointer to source bitmap
  255.  
  256.     mov di, 0                         ; initial size is nada
  257.  
  258.     lodsb                             ; load width byte
  259.     xor ah,ah                         ; convert to word
  260.     mov [bwidth],ax                   ; save for future reference
  261.     mov bl,al                         ; copy width byte to bl
  262.     lodsb                             ; load height byte. Is word since ah=0
  263.     mul bl                            ; mult height word by width byte
  264.     mov [input_size],ax               ;  giving pixel total and save
  265.  
  266. @@MainLoop:
  267.         mov bx,[scanx]                ; position in original bitmap
  268.         add bx,[scany]
  269.  
  270.     mov al,[si+bx]                ; get pixel
  271.     or  al,al                     ; skip empty pixels
  272.     jnz @@NoAdvance
  273.     jmp @@Advance
  274. @@NoAdvance:
  275.  
  276.             mov dx,[set_column]
  277.             cmp dx,[column]
  278.             je @@SameColumn
  279. @@ColumnLoop:
  280.                 add di, 5             ; size of code to adjust sprite
  281.                                       ; for new column
  282.                 inc dx
  283.                 cmp dx,[column]
  284.                 jl @@ColumnLoop
  285.  
  286.                 inc di                ; size of code to set VGA mask
  287.                 mov [set_column],dx
  288. @@SameColumn:
  289.             mov dx,[outputy]          ; calculate output position
  290.             add dx,[outputx]
  291.             sub dx,128
  292.  
  293.             add word ptr [scanx],4
  294.             mov cx,[scanx]            ; within four pixels of right edge?
  295.             cmp cx,[bwidth]
  296.             jge @@OnePixel
  297.  
  298.             inc word ptr [outputx]
  299.             mov ah,[si+bx+4]           ; get second pixel
  300.             or   ah,ah
  301.             jnz  @@TwoPixels
  302. @@OnePixel:
  303.                     cmp dx,127                ; can we use shorter form?
  304.                     jg @@OnePixLarge
  305.                     cmp dx,-128
  306.                     jl @@OnePixLarge
  307.                         add di, 3            ; 8-bit position in output
  308.                         jmp @@EmitOnePixel
  309. @@OnePixLarge:
  310.                         add di, 4            ; size of position in output
  311. @@EmitOnePixel:
  312.                     inc di
  313.             jmp short @@Advance
  314. @@TwoPixels:
  315.                     cmp dx,127
  316.                     jg @@TwoPixLarge
  317.                     cmp dx,-128
  318.                     jl @@TwoPixLarge
  319.                         add di, 3            ; 8-bit position in output
  320.                         jmp @@EmitTwoPixels
  321. @@TwoPixLarge:
  322.                         add di, 4            ; position in output
  323. @@EmitTwoPixels:
  324.                     add di, 2
  325.  
  326. @@Advance:
  327.         inc word ptr [outputx]
  328.         mov ax,[scanx]
  329.         add ax,4
  330.         cmp ax,[bwidth]
  331.         jl @@AdvanceDone
  332.             mov dx,[outputy]
  333.             add dx,[logical_width]
  334.             mov cx,[scany]
  335.             add cx,[bwidth]
  336.             cmp cx,[input_size]
  337.             jl @@NoNewColumn
  338.                 inc word ptr [column]
  339.                 mov cx,[column]
  340.                 cmp cx,4
  341.                 je @@Exit             ; Column 4: there is no column 4.
  342.                 xor cx,cx             ; scany and outputy are 0 again for
  343.                 mov dx,cx             ; the new column
  344. @@NoNewColumn:
  345.             mov [outputy],dx
  346.             mov [scany],cx
  347.             mov word ptr [outputx],0
  348.             mov ax,[column]
  349. @@AdvanceDone:
  350.             mov [scanx],ax
  351.     jmp @@MainLoop
  352.  
  353. @@Exit:
  354.     inc di
  355.     mov ax,di                         ; size of generated code
  356.  
  357.     pop ds
  358.     pop di
  359.     pop si
  360.     mov sp,bp
  361.     pop bp
  362.  
  363.     ret
  364. _x_sizeof_compiled_bitmap endp
  365.  
  366.  
  367. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  368. ; _x_put_cbitmap
  369. ;
  370. ; Displays a compiled bitmap generated by x_compile_bitmap at given
  371. ; coordinates, on a given screen page.
  372. ;
  373. ; C near-callable as:
  374. ; void x_put_cbitmap (int XPos, int YPos,
  375. ;                     unsigned int PageOffset, char far * Sprite);
  376. ; ax, bx, cx, and dx are squashed like insignificant insects.
  377.  
  378.     align   2
  379. _x_put_cbitmap proc
  380. ARG XPos:word,YPos:word,PageOffset:word,Sprite:dword
  381.  
  382.     push bp
  383.     mov bp, sp
  384.     push si
  385.     push ds
  386.  
  387.     mov ax,[_ScrnLogicalByteWidth]    ; global Xlib variable
  388.     mul word ptr [YPos]               ; height in bytes
  389.     mov si,[XPos]
  390.     mov bx,si
  391.     shr bx,1
  392.     shr bx,1                          ; width in VGA planes
  393.     add bx,ax
  394.     add bx,[PageOffset]               ;     (YPos * screen width) +
  395.     add bx,128                        ; ==> (Xpos / 4) + page base - 128
  396.  
  397.     mov dx,SC_INDEX
  398.     mov al,MAP_MASK
  399.     out dx,al
  400.     inc dx                            ; ready to send out other masks as bytes
  401.  
  402.     and si,3                          ; XPos & 3 = column
  403.     mov al,ColumnMask[si]
  404.     out dx,al
  405.  
  406.     mov si,bx                       ; position of upper-left corner of sprite
  407.  
  408.     mov bx,SCREEN_SEG
  409.     mov ds,bx                   ; We do this so the compiled shape won't need
  410.                                 ;  segment overrides.
  411.  
  412.     call dword ptr [Sprite]     ; the business end of the routine
  413.  
  414.     pop ds
  415.     pop si
  416.     pop bp
  417.  
  418.     ret
  419. _x_put_cbitmap endp
  420.  
  421. end
  422.  
  423.